package org.kfive.nova.io.netty.webchat;

import io.netty.channel.*;
import io.netty.handler.codec.http.*;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedNioFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.RandomAccessFile;
import java.net.URISyntaxException;
import java.net.URL;

/**
 * Created by admin on 2017-05-21.
 */
public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    private final static Logger log = LoggerFactory.getLogger(HttpRequestHandler.class);

    private String wsUri;

    private static File index;

    static {
        URL location = HttpRequestHandler.class.getProtectionDomain().getCodeSource().getLocation();
        try {
            String path = location.toURI()+"index.html";
            log.info("path="+path);
            path = !path.contains("files:")?path:path.substring(5);
            index = new File(path);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
    }

    public HttpRequestHandler(String wsUri){
        this.wsUri = wsUri;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
        //如果URI为/ws则使用websocket进行通讯
        if(msg.getUri().equalsIgnoreCase(wsUri)){
            ctx.fireChannelRead(msg.retain());
        }else {
            //处理Expect:100-Continue
            if(HttpHeaders.is100ContinueExpected(msg)){
                FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.CONTINUE);
                ctx.writeAndFlush(response);
            }
            RandomAccessFile file = new RandomAccessFile(index,"r");
            HttpResponse response = new DefaultFullHttpResponse(msg.getProtocolVersion(),HttpResponseStatus.OK);
            response.headers().set(HttpHeaders.Names.CONTENT_TYPE,"text/plain;charset=UTF-8");
            boolean keeplive = HttpHeaders.isKeepAlive(msg);
            if(keeplive){
                response.headers().set(HttpHeaders.Names.CONTENT_LENGTH,file.length());
                response.headers().set(HttpHeaders.Names.CONNECTION,HttpHeaders.Values.KEEP_ALIVE);
            }
            ctx.write(response);
            if(ctx.pipeline().get(SslHandler.class)==null){
                ctx.write(new DefaultFileRegion(file.getChannel(),0,file.length()));
            }else {
                ctx.write(new ChunkedNioFile(file.getChannel()));
            }
            ChannelFuture future = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
            if(!keeplive){
                future.addListener(ChannelFutureListener.CLOSE);
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        log.error(cause.getMessage());
        ctx.close();
    }
}
